var net = require('net')
var ACTIONS = require("./actions")
var ProxyPortServer = require('./ProxyPortServer')
const {Log} = require('./logger')

var dataSocketHold = new Map()

class DataServer{

    constructor(localPort, mainServer){
        this.localPort = localPort;
        this.dataServer = null;
        this.mainServer = mainServer
    }

    start(){

        this.dataServer = net.createServer((datasocket)=>{
        
            Log.info("datasocket connected")
            Log.info("local %s, %s", datasocket.localAddress, datasocket.localPort)
            Log.info("remote %s, %s", datasocket.remoteAddress, datasocket.remotePort)


            datasocket.once('data', (data)=>{

                var act = null
                try {
                    var str = data.toString().replace("\r\n", "")
                    Log.info("datasocket once data [%s]",str)
                    // 处理 rsp link
                    act = JSON.parse(str)
                } catch (error) {
                    Log.error("datasocket once error, maybe receive error data from out connecting", error)
                    datasocket.destroy()
                    return undefined;
                }


                switch(act.Action){
                    case ACTIONS.RESPLINK_STR: 
                        var connect_id = act.id
                        var nodeName = act.name
                        // node的服务端口
                        var port = act.port
                        datasocket.connection_id = connect_id
                        dataSocketHold.set(connect_id, datasocket)
                        try {
                            this.linkPort(connect_id)
                        } catch (error) {
                            Log.error("datasocket linkport error",error)
                            closeDataSocket(connect_id)
                        }
                        
                        // 发送RESPCONFIM
                        setTimeout(()=>{
                            var act =new ACTIONS.RESPCONFIRM(connect_id,port)
                            this.mainServer.send(nodeName, act)
                        }, 300)

                        break;
                    default:
                        Log.warn("datasocket receive error msg, close socket")
                        datasocket.destroy()
                        ;
                }
            })

            datasocket.on('close', (has_err)=>{
                Log.info("datasocket on close, %s", datasocket.connection_id)
                if(datasocket.connection_id){
                    ProxyPortServer.closeProxySocket(datasocket.connection_id)
                }
                datasocket.destroy()
            })

            datasocket.on('error', (err)=>{
                Log.error('datasocket on error %s',datasocket.connection_id, err)
                if(datasocket.connection_id){
                    ProxyPortServer.closeProxySocket(datasocket.connection_id)
                }
                datasocket.destroy()
            })


        })

        this.dataServer.listen(this.localPort, ()=>{
            Log.info("dataserver listen on port %s", this.localPort)
        })

    }
    linkPort(connect_id){
        var datasocket = dataSocketHold.get(connect_id)

        var proxyinfo = ProxyPortServer.getProxySocket(connect_id)

        proxyinfo.status = 'connect'

        var proxySocket = ProxyPortServer.getProxySocket(connect_id).socket

        datasocket.on('data', (data)=>{
            proxySocket.write(data)
        })

        proxySocket.on('data',(data)=>{
            datasocket.write(data)
        })

        Log.info("datasocket linkPort [%s]", connect_id)

    }
}


function getDataSocket(connect_id){
    return dataSocketHold.get(connect_id)
}

// 关闭数据端口
function closeDataSocket(connect_id){
    if(dataSocketHold.has(connect_id)){
        dataSocketHold.get(connect_id).destroy()
    }
    dataSocketHold.delete(connect_id)
}

DataServer.closeDataSocket = closeDataSocket

module.exports = DataServer